#include <iostream>
#include <pthread.h>
#include <queue>

// 问题1：为什么加了template <typenameT>在class的前面，class里面的错误就不报错了
//没有实例化，换用clang
template <typename T> class BlockQueue {
private:
  bool IsFull() { return _q.size() == _cap; }
  bool IsEmpty() { return _q.empty(); }

public:
  BlockQueue(const size_t &cap) : _cap(cap){};
  BlockQueue(const BlockQueue<T> &) = delete;
  BlockQueue &operator=(const BlockQueue<T> &) = delete;

  void Push(const T &val) {
    pthread_mutex_lock(&_mtx);
    while (IsFull()) {
      pthread_cond_wait(&_producter_cond, &_mtx);
    }

    _q.push(val);
    //先叫再解锁，否则反之锁被别人抢走了
    pthread_cond_signal(&_consumer_cond);
    pthread_mutex_unlock(&_mtx);
  }

  const T Pop() {
    pthread_mutex_lock(&_mtx);
    while (IsEmpty()) {
      pthread_cond_wait(&_consumer_cond, &_mtx);
    }

    T val = _q.front();
    _q.pop();
    pthread_cond_signal(&_producter_cond);
    pthread_mutex_unlock(&_mtx);

    return val;
  }

  ~BlockQueue(){};

private:
  std::queue<T> _q;
  size_t _cap;
  pthread_mutex_t _mtx = PTHREAD_MUTEX_INITIALIZER;
  pthread_cond_t _producter_cond = PTHREAD_COND_INITIALIZER;
  pthread_cond_t _consumer_cond = PTHREAD_COND_INITIALIZER;
  //问题2：waitnum的作用是什么
  // int _producter_wait_num = 0;
  // int _consumer_wait_num = 0;
};